﻿using Werd = Microsoft.Office.Interop.Word;
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Office.Core;
using Microsoft.Win32;

namespace MaskData
{
    class Word
    {
        /************************************************************
         * WordOpenDocuments() is the main function that spawns a   * 
         * new instance of Microsoft Word. It is very important     * 
         * because our scanning functions rely on it to start the   * 
         * process of actually reading our documents and then       *
         * calling the necessary hash functions.                    *
         ************************************************************/

        // Create bool variable to determine how to cleanup.
        bool showSuccess = false;

        // Create a null object variable for our missing object variables
        // when opening Word documents.
        object nullobj = System.Reflection.Missing.Value;

        public void WordOpenDocuments(object documentPath)
        {
            try
            {
                // Initialize an instance of Word.
                Werd.Application wordApp = new Werd.ApplicationClass();

                // Setup so user can't see Word.
                wordApp.Visible = true; // Debugging

                // Open the document from the documentPath variable.
                Werd.Document wordDocument = wordApp.Documents.Open(ref documentPath,
                    ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                    ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                    ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                // Call our hashing function. Pass the called application and document.
                WordScan(wordApp, wordDocument);
            }
            catch (Exception ee)
            {
                MessageBox.Show("Exception: " + ee);
            }
        }

        public void WordScan(Werd.Application _wordApp, Werd.Document _wordDocument)
        {           
            // Instantiate a new instance of mdOptions so we
            // can access our objects.
            mdMain _mdMain = new mdMain();

            // Read what the values are for the checkboxes first and assign them to a string.
            string _wordEnable = Convert.ToString(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Mask Data\", "WordEnableHash", "Unchecked"));
            string _dataSSN = Convert.ToString(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Mask Data\", "SSNHash", "Unchecked"));
            string _dataCC = Convert.ToString(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Mask Data\", "CCHash", "Unchecked"));
            string _dataWells = Convert.ToString(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Mask Data\", "WellsHash", "Unchecked"));
            string _dataBA = Convert.ToString(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Mask Data\", "BAHash", "Unchecked"));

            // If Word is enabled, and everything is not checkmarked, then search for every type and hash.
            if (_wordEnable == "Checked")
                if (_dataSSN == "Unchecked")
                    if (_dataCC == "Unchecked")
                        if (_dataWells == "Unchecked")
                            if (_dataBA == "Unchecked")
                            {
                                try
                                {
                                    object replaceSSN = Werd.WdReplace.wdReplaceAll;

                                    _wordApp.Selection.Find.ClearFormatting();
                                    _wordApp.Selection.Find.MatchWildcards = true;
                                    _wordApp.Selection.Find.Text = _mdMain.ssnExpressions;
                                    string textMatchSSN = _wordApp.Selection.Find.Text.ToString();

                                    string replaceSSNHash = SHA2Hash.ComputeHash(textMatchSSN, "SHA256", null);

                                    _wordApp.Selection.Find.Replacement.ClearFormatting();
                                    _wordApp.Selection.Find.Replacement.Text = replaceSSNHash;

                                    _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                        ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                        ref replaceSSN, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                                    showSuccess = true;

                                    try
                                    {
                                        object replaceSSN2 = Werd.WdReplace.wdReplaceAll;

                                        _wordApp.Selection.Find.ClearFormatting();
                                        _wordApp.Selection.Find.MatchWildcards = true;
                                        _wordApp.Selection.Find.Text = _mdMain.ssnExpressions2;
                                        string textMatchSSN2 = _wordApp.Selection.Find.Text.ToString();

                                        string replaceSSN2Hash = SHA2Hash.ComputeHash(textMatchSSN2, "SHA256", null);

                                        _wordApp.Selection.Find.Replacement.ClearFormatting();
                                        _wordApp.Selection.Find.Replacement.Text = replaceSSN2Hash;

                                        _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                            ref replaceSSN2, ref nullobj, ref nullobj, ref nullobj, ref nullobj);
                                    }
                                    catch (Exception ex)
                                    {
                                        StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                                        _writeLogs.WriteLine(ex);
                                        _writeLogs.Close();
                                        _writeLogs.Dispose();

                                        MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                                    }

                                    try
                                    {
                                        object replaceCC = Werd.WdReplace.wdReplaceAll;

                                        _wordApp.Selection.Find.ClearFormatting();
                                        _wordApp.Selection.Find.MatchWildcards = true;
                                        _wordApp.Selection.Find.Text = _mdMain.ccExpressions;
                                        string textMatchCC = _wordApp.Selection.Find.Text.ToString();

                                        string replaceCCHash = SHA2Hash.ComputeHash(textMatchCC, "SHA256", null);

                                        _wordApp.Selection.Find.Replacement.ClearFormatting();
                                        _wordApp.Selection.Find.Replacement.Text = replaceCCHash;

                                        _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                            ref replaceCC, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                                        showSuccess = true;
                                    }
                                    catch (Exception ex)
                                    {
                                        StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                                        _writeLogs.WriteLine(ex);
                                        _writeLogs.Close();
                                        _writeLogs.Dispose();

                                        MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                                    }

                                    try
                                    {
                                        object replaceWF = Werd.WdReplace.wdReplaceAll;

                                        _wordApp.Selection.Find.ClearFormatting();
                                        _wordApp.Selection.Find.MatchWildcards = true;
                                        _wordApp.Selection.Find.Text = _mdMain.wfBankAccountExpressions;
                                        string textMatchWF = _wordApp.Selection.Find.Text.ToString();

                                        string replaceWFHash = SHA2Hash.ComputeHash(textMatchWF, "SHA256", null);

                                        _wordApp.Selection.Find.Replacement.ClearFormatting();
                                        _wordApp.Selection.Find.Replacement.Text = replaceWFHash;

                                        _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                            ref replaceWF, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                                        showSuccess = true;
                                    }
                                    catch (Exception ex)
                                    {
                                        StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                                        _writeLogs.WriteLine(ex);
                                        _writeLogs.Close();
                                        _writeLogs.Dispose();

                                        MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                                    }

                                    try
                                    {
                                        object replaceBA = Werd.WdReplace.wdReplaceAll;

                                        _wordApp.Selection.Find.ClearFormatting();
                                        _wordApp.Selection.Find.MatchWildcards = true;
                                        _wordApp.Selection.Find.Text = _mdMain.baBankAccountExpressions;
                                        string textMatchBA = _wordApp.Selection.Find.Text.ToString();

                                        string replaceBAHash = SHA2Hash.ComputeHash(textMatchBA, "SHA256", null);

                                        _wordApp.Selection.Find.Replacement.ClearFormatting();
                                        _wordApp.Selection.Find.Replacement.Text = replaceBAHash;

                                        _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                            ref replaceBA, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                                        showSuccess = true;
                                    }
                                    catch (Exception ex)
                                    {
                                        StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                                        _writeLogs.WriteLine(ex);
                                        _writeLogs.Close();
                                        _writeLogs.Dispose();

                                        MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                                    _writeLogs.WriteLine(ex);
                                    _writeLogs.Close();
                                    _writeLogs.Dispose();

                                    MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                            This error has been logged at C:\Program Files\Mask Data\error.txt. 
                            Please send the full log to whughes05@gmail.com. Thank you.");
                                }
                            }

            // If Word is enabled, AND ONLY the Social Security type is checkmarked
            // then find a match and hash.
            if (_wordEnable == "Checked")
                if (_dataSSN == "Checked")
                {
                    try
                    {
                        object replaceSSN = Werd.WdReplace.wdReplaceAll;

                        _wordApp.Selection.Find.ClearFormatting();
                        _wordApp.Selection.Find.MatchWildcards = true;
                        _wordApp.Selection.Find.Text = _mdMain.ssnExpressions;
                        string textMatchSSN = _wordApp.Selection.Find.Text.ToString();

                        string replaceSSNHash = SHA2Hash.ComputeHash(textMatchSSN, "SHA256", null);

                        _wordApp.Selection.Find.Replacement.ClearFormatting();
                        _wordApp.Selection.Find.Replacement.Text = replaceSSNHash;

                        _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                            ref replaceSSN, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                        showSuccess = true;
                        try
                        {
                            object replaceSSN2 = Werd.WdReplace.wdReplaceAll;

                            _wordApp.Selection.Find.ClearFormatting();
                            _wordApp.Selection.Find.MatchWildcards = true;
                            _wordApp.Selection.Find.Text = _mdMain.ssnExpressions2;
                            string textMatchSSN2 = _wordApp.Selection.Find.Text.ToString();

                            string replaceSSN2Hash = SHA2Hash.ComputeHash(textMatchSSN2, "SHA256", null);

                            _wordApp.Selection.Find.Replacement.ClearFormatting();
                            _wordApp.Selection.Find.Replacement.Text = replaceSSN2Hash;

                            _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                                ref replaceSSN2, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                            showSuccess = true;
                        }
                        catch (Exception ex)
                        {
                            StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                            _writeLogs.WriteLine(ex);
                            _writeLogs.Close();
                            _writeLogs.Dispose();

                            MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                        }
                    }
                    catch (Exception ex)
                    {
                        StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                        _writeLogs.WriteLine(ex);
                        _writeLogs.Close();
                        _writeLogs.Dispose();

                        MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                    }
                }

            // If Excel is enabled, AND ONLY the credit card type is checkmarked
            // then find a match and hash.
            if (_wordEnable == "Checked")
                if (_dataCC == "Checked")
                {
                    try
                    {
                        object replaceCC = Werd.WdReplace.wdReplaceAll;

                        _wordApp.Selection.Find.ClearFormatting();
                        _wordApp.Selection.Find.MatchWildcards = true;
                        _wordApp.Selection.Find.Text = _mdMain.ccExpressions;
                        string textMatchCC = _wordApp.Selection.Find.Text.ToString();

                        string replaceCCHash = SHA2Hash.ComputeHash(textMatchCC, "SHA256", null);

                        _wordApp.Selection.Find.Replacement.ClearFormatting();
                        _wordApp.Selection.Find.Replacement.Text = replaceCCHash;

                        _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                            ref replaceCC, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                        showSuccess = true;
                    }
                    catch (Exception ex)
                    {
                        StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                        _writeLogs.WriteLine(ex);
                        _writeLogs.Close();
                        _writeLogs.Dispose();

                        MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                    }
                }

            // If Excel is enabled, AND ONLY the Wells Fargo type is checkmarked
            // then find a match and hash.
            if (_wordEnable == "Checked")
                if (_dataWells == "Checked")
                {
                    try
                    {
                        object replaceWF = Werd.WdReplace.wdReplaceAll;

                        _wordApp.Selection.Find.ClearFormatting();
                        _wordApp.Selection.Find.MatchWildcards = true;
                        _wordApp.Selection.Find.Text = _mdMain.wfBankAccountExpressions;
                        string textMatchWF = _wordApp.Selection.Find.Text.ToString();

                        string replaceWFHash = SHA2Hash.ComputeHash(textMatchWF, "SHA256", null);

                        _wordApp.Selection.Find.Replacement.ClearFormatting();
                        _wordApp.Selection.Find.Replacement.Text = replaceWFHash;

                        _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                            ref replaceWF, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                        showSuccess = true;
                    }
                    catch (Exception ex)
                    {
                        StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                        _writeLogs.WriteLine(ex);
                        _writeLogs.Close();
                        _writeLogs.Dispose();

                        MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                    }
                }

            // If Excel is enabled, AND ONLY the Bank of America type is checkmarked
            // then find a match and hash.
            if (_wordEnable == "Checked")
                if (_dataBA == "Checked")
                {
                    try
                    {
                        object replaceBA = Werd.WdReplace.wdReplaceAll;

                        _wordApp.Selection.Find.ClearFormatting();
                        _wordApp.Selection.Find.MatchWildcards = true;
                        _wordApp.Selection.Find.Text = _mdMain.baBankAccountExpressions;
                        string textMatchBA = _wordApp.Selection.Find.Text.ToString();

                        string replaceBAHash = SHA2Hash.ComputeHash(textMatchBA, "SHA256", null);

                        _wordApp.Selection.Find.Replacement.ClearFormatting();
                        _wordApp.Selection.Find.Replacement.Text = replaceBAHash;

                        _wordApp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
                            ref replaceBA, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

                        showSuccess = true;
                    }
                    catch (Exception ex)
                    {
                        StreamWriter _writeLogs = new StreamWriter(_mdMain.AppPath);
                        _writeLogs.WriteLine(ex);
                        _writeLogs.Close();
                        _writeLogs.Dispose();

                        MessageBox.Show(@"An error with the program has occurred, however the program is still operational. 
                                                    This error has been logged at C:\Program Files\Mask Data\error.txt. 
                                                    Please send the full log to whughes05@gmail.com. Thank you.");
                    }
                }

            // Report success.
            if (showSuccess == true)
            {
                Form newForm = new Form();
                newForm.TopMost = true;
                MessageBox.Show(newForm, "Mask Data has finished. Please review your file for any hashed fields.", "Mask Data", MessageBoxButtons.OK);
                newForm.TopMost = false;
            }
            else
            {
                Form newForm = new Form();
                newForm.TopMost = true;
                MessageBox.Show(newForm, @"Mask Data either didn't find anything to mask or you didn't select an option on the main screen.", "Mask Data", MessageBoxButtons.OK);
                newForm.TopMost = false;
            }

            // Shutdown instance of Word.
            _wordApp.Quit(ref nullobj, ref nullobj, ref nullobj);

            // Release memory.
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Marshal.ReleaseComObject(_wordDocument);
            Marshal.ReleaseComObject(_wordApp);
        }
    }
}